package com.qdx.qiuzidao;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import com.aliyun.im.AliVCIMEngine;
import com.aliyun.im.AliVCIMGroupInterface;
import com.aliyun.im.AliVCIMMessageInterface;
import com.aliyun.im.common.Error;
import com.aliyun.im.interaction.ImAuth;
import com.aliyun.im.interaction.ImGroupInfoStatus;
import com.aliyun.im.interaction.ImGroupListener;
import com.aliyun.im.interaction.ImGroupMuteStatus;
import com.aliyun.im.interaction.ImJoinGroupReq;
import com.aliyun.im.interaction.ImJoinGroupRsp;
import com.aliyun.im.interaction.ImLeaveGroupReq;
import com.aliyun.im.interaction.ImLoginReq;
import com.aliyun.im.interaction.ImMessage;
import com.aliyun.im.interaction.ImMessageListener;
import com.aliyun.im.interaction.ImSdkCallback;
import com.aliyun.im.interaction.ImSdkConfig;
import com.aliyun.im.interaction.ImSdkValueCallback;
import com.aliyun.im.interaction.ImUser;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Logger;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;

abstract class AliMessage {
    private static final String TAG = "AliMessage";
    private static EventChannel.EventSink events;
    private static AliVCIMMessageInterface messageInterface;
    private static AliVCIMGroupInterface groupInterface;
    static boolean isInit = false;
    static boolean isDebug = false;

    static void init(Context context,@NonNull FlutterEngine flutterEngine){
        if(!isInit) {
            try{
                InputStream inputStream = context.getAssets().open("config.yaml");
                Yaml yaml = new Yaml();
                Map<String, Object> data = yaml.load(inputStream);
                // 可以使用data来访问YAML文件中的内容
                Map<String, Object> configMap = (Map<String, Object>) data.get("config");
                isDebug = (boolean) configMap.get("isDebug");
            }catch (Exception e){
                Log.e(TAG,e.getMessage());
            }
            isInit = true;
            ImSdkConfig config = new ImSdkConfig();
            if(isDebug) {
                config.appId = "035367352cd4";
                config.appSign = "H4sIAAAAAAAE/wCQAG//zguHB+lYCilkv7diSkk4GoWY/cwPzh8nAYT5XA7dnFO8768k+/Bo4AoZeg4iPNBpZff+9bl1q200f0Lrc4OmYZjklVsFVdJ6BOqkQeKe3jfuKfer9wwbZfLU/NBuxTi5+y7jGEw/AWy/QsNSIDJDKmjq2cq2NGEtkU8VCat5ozCNEm5aNpJE+INEz+YcHaVlAAAA//8BAAD//5Eqs7eQAAAA";
            }else{
                config.appId = "5f4cbcb58e31";
                config.appSign = "H4sIAAAAAAAE/wCQAG//zguHB+lYCilkv7diSkk4Go4U6gElGjCNwXcdjGnJjC7m8OmA9C33Woc5FLiQeMh95cfnoacykF2InHf1fWcmieDzsSgrEJH84tOkc8K3mWvEgHfj0FEWz3mWFB2AA5LyFWvN2pt9fJ8qUQs8uPCuFhW29RN8SqWyqT8aX19YxYgzl0rGHy9UDOv8V5EKWBSxAAAA//8BAAD//2dAIsmQAAAA";
            }
            int ret = AliVCIMEngine.instance().init(context, config);

            messageInterface = AliVCIMEngine.instance().getMessageManager();
            groupInterface = AliVCIMEngine.instance().getGroupManager();

            MethodChannel methodChannel = new MethodChannel(
                flutterEngine.getDartExecutor().getBinaryMessenger(),
                "ali_message/method"
            );
            methodChannel.setMethodCallHandler((call, result) -> {
                switch (call.method) {
                    case "login" -> {
                        JsonObject json = JsonParser.parseString((String) call.arguments).getAsJsonObject();
                        JsonObject authInfo = json.getAsJsonObject("auth");
                        ImUser user = new ImUser(
                            authInfo.get("userId").getAsString(),
                            json.get("userExtension").getAsString()
                        );
                        ImAuth auth = new ImAuth(
                                authInfo.get("nonce").getAsString(),
                                authInfo.get("timestamp").getAsLong(),
                                authInfo.get("role").getAsString(),
                                json.get("appToken").getAsString()
                        );
                        login(user, auth, result);
                    }
                    case "logout" -> logout(result);
                    case "enterGroup" -> enterGroup((String) call.arguments, result);
                    case "leaveGroup" -> leaveGroup((String) call.arguments, result);
                    default -> result.notImplemented();
                }
            });
            onMessageListen(methodChannel);
        }
    }

    static  void sendMessage(Message message){
        if(events != null){
            new Handler(Looper.getMainLooper()).post(() -> {
                try {
                    String json = new Gson().toJson(message);
                    events.success(json);
                }catch (Exception e){
                    Logger.getLogger(Objects.requireNonNull(e.getMessage()));
                }
            });
        }
    }

    static void startEvents(@NonNull FlutterEngine flutterEngine){
        EventChannel eventChannel = new EventChannel(
            flutterEngine.getDartExecutor(),
            "ali_message/event"
        );
        eventChannel.setStreamHandler(new EventChannel.StreamHandler() {
            @Override
            public void onListen(Object o, EventChannel.EventSink eventSink) {
                events = eventSink;
            }
            @Override
            public void onCancel(Object o) {
                events = null;
            }
        });
    }

    static void login(ImUser user, ImAuth auth, MethodChannel.Result result){
        ImLoginReq req = new ImLoginReq();
        req.user = user;
        req.userAuth = auth;
        AliVCIMEngine.instance().login(req, new ImSdkCallback() {
            @Override
            public void onSuccess() {
                result.success("login success");
            }

            @Override
            public void onFailure(Error error) {
                result.error(error.msg,error.toString(),"");
            }
        });
    }

    static void logout(MethodChannel.Result result){
        AliVCIMEngine.instance().logout(new ImSdkCallback() {
            @Override
            public void onSuccess() {
                result.success("logout success");
            }

            @Override
            public void onFailure(Error error) {
                result.error(error.msg,error.toString(),"");
            }
        });
    }

    static void enterGroup(String groupId,MethodChannel.Result result){
        ImJoinGroupReq req = new ImJoinGroupReq();
        req.groupId = groupId;
        groupInterface.joinGroup(req, new ImSdkValueCallback<ImJoinGroupRsp>() {
            @Override
            public void onSuccess(ImJoinGroupRsp data) {
                executeWithTryCatch(()->result.success("enter success"));
            }

            @Override
            public void onFailure(Error error) {
                executeWithTryCatch(()->result.error(error.msg, error.toString(),""));
            }
        });
    }

    static void leaveGroup(String groupId,MethodChannel.Result result){
        ImLeaveGroupReq req = new ImLeaveGroupReq();
        req.groupId = groupId;
        groupInterface.leaveGroup(req, new ImSdkCallback() {
            @Override
            public void onSuccess() {
                executeWithTryCatch(()->result.success("enter success"));
            }

            @Override
            public void onFailure(Error error) {
                executeWithTryCatch(()->result.error(error.msg, error.toString(),""));
            }
        });
    }

    static void onMessageListen(MethodChannel methodChannel){
        messageInterface.addMessageListener(new ImMessageListener() {

            @Override
            public void onRecvC2cMessage(ImMessage msg) {

            }
            @Override
            public void onRecvGroupMessage(ImMessage msg, String groupId) {
                new Handler(Looper.getMainLooper()).post(() -> {
                    try {
                        methodChannel.invokeMethod("errorMsg", new Gson().toJson(msg));
                    }catch (Exception e){
                        Logger.getLogger(Objects.requireNonNull(e.getMessage()));
                    }
                });

                if(Objects.equals(msg.sender.userExtension, "")) {
                    return;
                }
                if(msg.type == 1){
                    sendMessage(new Message(
                            groupId,
                            msg.sender.userId,
                            getInfo(msg.sender.userExtension).get("userName"),
                            getInfo(msg.sender.userExtension).get("userAvatar"),
                            msg.data,
                            msg.messageId,
                            MessageType.SEND_MESSAGE
                    ));
                }else if(msg.type == 3){
                    sendMessage(new Message(
                        groupId,
                        msg.sender.userId,
                        getInfo(msg.sender.userExtension).get("userName"),
                        getInfo(msg.sender.userExtension).get("userAvatar"),
                        msg.data,
                        msg.messageId,
                        MessageType.FOCUS
                    ));
                }else if(msg.type == 4){
                    sendMessage(new Message(
                        groupId,
                        msg.sender.userId,
                        getInfo(msg.sender.userExtension).get("userName"),
                        getInfo(msg.sender.userExtension).get("userAvatar"),
                        msg.data,
                        msg.messageId,
                        MessageType.GIFT
                    ));
                }else if(msg.type == 99){
                    sendMessage(new Message(
                    groupId,
                    "",
                    "",
                    "",
                    "",
                    msg.messageId,
                    MessageType.COMPLETION
                    ));
                }else{
                    sendMessage(new Message(
                            groupId,
                            msg.sender.userId,
                            getInfo(msg.sender.userExtension).get("userName"),
                            getInfo(msg.sender.userExtension).get("userAvatar"),
                            msg.data,
                            msg.messageId,
                            MessageType.OTHER
                    ));
                }
            }

            @Override
            public void onDeleteGroupMessage(String msgId, String groupId) {
                sendMessage(new Message(
                    groupId,
                    "",
                    "",
                    "",
                    "",
                    msgId,
                    MessageType.DELETE_MESSAGE
                ));
            }
        });
        groupInterface.addGroupListener(new ImGroupListener() {
            @Override
            public void onMemberChange(String groupId, int memberCount, ArrayList<ImUser> joinUsers, ArrayList<ImUser> leaveUsers) {
                for (ImUser imUser : joinUsers){
                    if(Objects.equals(imUser.userExtension, "")) return;
                    sendMessage(new Message(
                        groupId,
                        imUser.userId,
                        getInfo(imUser.userExtension).get("userName"),
                        getInfo(imUser.userExtension).get("userAvatar"),
                        "加入直播间",
                        "",
                        MessageType.JOIN_GROUP
                    ));
                }
                for (ImUser imUser : leaveUsers){
                    if(Objects.equals(imUser.userExtension, "")) return;
                    sendMessage(new Message(
                            groupId,
                            imUser.userId,
                            getInfo(imUser.userExtension).get("userName"),
                            getInfo(imUser.userExtension).get("userAvatar"),
                            "离开直播间",
                            "",
                            MessageType.EXIT_GROUP
                    ));
                }
            }

            @Override
            public void onExit(String groupId, int i) {

            }

            @Override
            public void onMuteChange(String groupId, ImGroupMuteStatus imGroupMuteStatus) {
                if(imGroupMuteStatus.muteAll){
                    sendMessage(new Message(
                        groupId,
                        "",
                        "",
                        "",
                        "全体禁言",
                        "",
                        MessageType.MUTE_ALL
                    ));
                    sendMessage(new Message(
                            groupId,
                            "",
                            "",
                            "",
                            "解除全体禁言",
                            "",
                            MessageType.UNMUTE_ALL
                    ));
                }else {
                    for (String userId : imGroupMuteStatus.muteUserList){
                        sendMessage(new Message(
                            groupId,
                            userId,
                            "",
                            "",
                            "被禁言",
                            "",
                            MessageType.UNMUTE
                        ));
                    }
                    for (String userId : imGroupMuteStatus.whiteUserList){
                        sendMessage(new Message(
                            groupId,
                            userId,
                            "",
                            "",
                            "取消禁言",
                            "",
                            MessageType.UNMUTE
                        ));
                    }
                }
            }

            @Override
            public void onInfoChange(String groupId, ImGroupInfoStatus imGroupInfoStatus) {

            }
        });

    }

    static Map<String,String> getInfo(String info){
        try {
            Map<String, String> map = new HashMap<String, String>();
            JsonObject json = JsonParser.parseString(info).getAsJsonObject();
            if(json.get("userName") != null) {
                map.put("userName", json.get("userName").getAsString());
            }
            if(json.get("userAvatar") != null) {
                map.put("userAvatar", json.get("userAvatar").getAsString());
            }
            return map;
        }catch (Exception e){
            Map<String, String> map = new HashMap<String, String>();
            map.put("userName", "");
            map.put("userAvatar", "");
            return map;
        }
    }

    @FunctionalInterface
    public interface ThrowingRunnable {
        void run() throws Exception;
    }

    public static void executeWithTryCatch(ThrowingRunnable runnable) {
        try {
            runnable.run();
        } catch (Exception e) {
            // 在这里处理异常，比如打印日志、提示用户等
            Log.e("executeWithTryCatch", "Caught an exception: ", e);
        }
    }
}
